<template>
    <div>
        <el-form
            ref="formData"
            :rules="rules"
            :model="formData"
            label-position="right"
            label-width="auto"
            v-loading="formLoading"
        >
            <el-row class="formBox" v-for="(item, index) in formItems" :key="index">
                <!-- 大标题 -->
                <el-col :span="item.colspan || 24" v-if="item.title" class="formTitle">
                    <div>{{item.title}}</div>
                </el-col>
                <!-- 大横线 -->
                <el-col :span="item.colspan || 24" v-else-if="item.border">
                    <el-divider></el-divider>
                </el-col>
                <!-- 富文本 -->
                <el-col :span="item.colspan || 24" v-else-if="item.type=='textarea'">
                    <el-form-item :label="item.label" :prop="item.key" v-if="item.tip">
                        <el-tooltip class="item" effect="dark" :content="item.tip" placement="top">
                            <el-input
                                :style="{'width':item.width?item.width+'px':'100%'}"
                                :resize="item.resize || 'vertical'"
                                v-model="formData[item.key]"
                                :placeholder="item.placeholder || $t('page.system.form.please')  + ' ' + item.label"
                                :autosize="{ minRows: item.minRows || 2, maxRows: item.maxRows || 4}"
                                type="textarea"
                                :disabled="formData.id && item.disabled"
                                :readonly="item.readonly"
                            />
                        </el-tooltip>
                    </el-form-item>
                    <el-form-item :label="item.label" :prop="item.key" v-else>
                        <el-input
                            :style="{'width':item.width?item.width+'px':'100%'}"
                            :resize="item.resize || 'vertical'"
                            v-model="formData[item.key]"
                            :placeholder="item.placeholder || $t('page.system.form.please') + ' ' + item.label"
                            :autosize="{ minRows: item.minRows || 2, maxRows: item.maxRows || 4}"
                            type="textarea"
                            :disabled="formData.id && item.disabled"
                            :readonly="item.readonly"
                        />
                    </el-form-item>
                </el-col>
                <!-- 单选 -->
                <el-col
                    :span="item.colspan || 24"
                    v-else-if="item.type=='radio'"
                >
                    <el-form-item :label="item.label" :prop="item.key">
                        <el-radio-group
                            :disabled="formData.id && item.disabled"
                            v-model="formData[item.key]"
                            @change="radioChange"
                        >
                            <el-radio v-for="opt in item.options" :key="opt.key" :label="opt.value">{{ opt.key }}</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </el-col>
                <!-- 选择框 -->
                <el-col
                    :span="item.colspan || 24"
                    v-else-if="item.type=='select'"
                >
                    <el-form-item :label="item.label" :prop="item.key" >
                        <selectpart
                            :item="item"
                            :formData="formData"
                            :vModel="selectDataFun(formData[item.key],item.key)"
                            @selectChange="selectChange($event,item.key)"
                        ></selectpart>
                    </el-form-item>
                </el-col>
                <!--时间-->
                <el-col
                    :span="item.colspan || 24"
                    v-else-if="item.type === 'time'"
                >
                    <el-form-item :label="item.label" :prop="item.key">
                        <el-time-picker
                            v-model="formData[item.key]"
                            :picker-options="{selectableRange: '00:00:00 - 23:59:59'}"
                            placeholder="请选择时间"
                        ></el-time-picker>
                    </el-form-item>
                </el-col>
                <!--日期时间-->
                <el-col
                    :span="item.colspan || 24"
                    v-else-if="item.type === 'datetime'"
                >
                    <el-form-item :label="item.label" :prop="item.key">
                        <el-date-picker
                            v-model="formData[item.key]"
                            type="datetime"
                            placeholder="选择日期时间"
                            default-time="12:00:00"
                            value-format="yyyy-MM-dd HH:mm:ss"
                            :style="{'width':item.width?item.width+'px':'100%'}"
                        >
                        </el-date-picker>
                    </el-form-item>
                </el-col>
                <!-- 树状结构 -->
                <el-col
                    :span="item.colspan || 24"
                    v-else-if="item.type=='tree'"
                >
                    <el-form-item :label="item.label" :prop="item.key">
                        <tree
                            ref="treeDom"
                            :treeList="item.treeList"
                            :treeData="getTreeDataFun(formData[item.key])"
                            :defaultProps="item.defaultProps"
                            @treeChange="treeChange($event,item.key)"
                        ></tree>
                    </el-form-item>
                </el-col>
                <!-- 输入框-->
                <el-col
                    :span="item.colspan || 24"
                    v-else
                    v-show="item.type!='amap'"
                >
                    <el-form-item :label="item.label" :prop="item.key" v-if="item.tip">
                        <el-tooltip class="item" effect="dark" :content="item.tip" placement="top">
                            <el-input
                                v-model="formData[item.key]"
                                :placeholder="item.placeholder || $t('page.system.form.please')  + ' ' + item.label"
                                :style="{'width':item.width?item.width+'px':'100%'}"
                                class="filter-item"
                                :disabled="formData.id && item.disabled"
                                clearable
                            />
                        </el-tooltip>
                    </el-form-item>
                    <el-form-item :label="item.label" :prop="item.key" v-else>
                        <el-input
                            v-model="formData[item.key]"
                            :placeholder="item.placeholder || $t('page.system.form.please') + ' ' + item.label"
                            :style="{'width':item.width?item.width+'px':'100%'}"
                            class="filter-item"
                            :disabled="formData.id && item.disabled"
                            clearable
                        />
                        <span v-if="item.Suffix">{{item.Suffix}}</span>
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <div class="clearfix"></div>
        <div slot="footer" style="text-align: right;">
            <el-button
                type="primary"
                @click="submitEvent('formData')"
                :loading="formLoading"
                size="medium"
            >{{ $t('page.system.button.confirm') }}</el-button>
            <el-button @click="cancelEvent" size="medium">{{ $t('page.system.button.cancel') }}</el-button>
        </div>
    </div>
</template>
<script>
    export default {
        name: "forms",
        components: {
            tree: () => import('./tree'),
            selectpart: () => import('./select'),
        },
        props: {
            formItems: {
                type: Array,
                default() {
                    return [];
                }
            },
            formData: {
                type: Object,
                default() {
                    return {};
                }
            },
            formLoading: {
                type: Boolean,
                default() {
                    return false;
                }
            }
        },
        data() {
            return {
                selectData: [],
                itemNum: 8,
                rules: {},
                ruleTypes: {
                    NotBlank: { required: true, trigger: "blur" },
                    Email: { required: true, type: 'email', trigger: ['blur', 'change']},
                    NUM: {
                        required: true,
                        pattern: /^[1-9]\d*$/,
                        message: "只能输入非零正整数",
                        trigger: "blur"
                    },
                    NUM0: {
                        required: true,
                        pattern: /^[0-9]\d*$/,
                        message: "只能输入非负整数",
                        trigger: "blur"
                    },
                    FNUM: {
                        required: true,
                        pattern: /^\d+(\.\d+)?$/,
                        message: "只能输入非负数",
                        trigger: "blur"
                    },
                    NUM1: {
                        required: true,
                        pattern: /^-?[0-9]\d*$/,
                        message: "只能输入整数",
                        trigger: "blur"
                    },
                    ENNUM: {
                        required: true,
                        pattern: /^[0-9a-zA-Z]*$/g,
                        message: "只能输入英文或者数字",
                        trigger: "blur"
                    },
                    DEC: {
                        required: true,
                        pattern: /\d+\.?\d{0,2}/,
                        message: "只能输入数字或小数",
                        trigger: "blur"
                    },
                    CN: {
                        required: true,
                        pattern: /[\u4e00-\u9fa5]/g,
                        message: "只能输入中文",
                        trigger: "blur"
                    }
                }
            };
        },
        created() {
            this.initRules();
        },
        computed: {},
        watch: {},
        methods: {
            ifshow(obj) {
                if (!obj) {
                    return true;
                } else {
                    if (this.formData[obj.type] == obj.result) {
                        return true;
                    } else {
                        return false;
                    }
                }
            },
            getLocation(data, e) {
                this.$set(this.formData, e.longitude, data.position[0]);
                this.$set(this.formData, e.latitude, data.position[1]);
                this.$set(this.formData, e.address, data.address);
            },
            // 单选操作
            radioChange(e) {
                this.$emit("radioChange", e);
            },
            submitEvent(formName) {
                this.$refs[formName].validate(valid => {
                    if (valid) {
                        /**
                         * 获取到的数据,如果是数组转成字符串
                         */
                        let param = this.formData;
                        Object.keys(param).forEach(i => {
                            if (param[i] instanceof Array) {
                                param[i] = param[i].join(",");
                            }
                        });
                        this.$emit("submitEvent");
                    } else {
                        console.log("error submit!!");
                        return false;
                    }
                });
            },
            cancelEvent() {
                this.$emit("cancelEvent");
            },
            isDatePicker(type) {
                return [
                    "year",
                    "month",
                    "date",
                    "week",
                    "datetime",
                    "datetimerange",
                    "daterange"
                ].includes(type);
            },

            uploadSuccess(e, key, type) {
                // this.formData[key] = e; //此方法不能双向修改
                if (type == "file") {
                    e = e[0].url;
                } else if (type == "imageMore") {
                    const arr = [];
                    e.forEach(e => {
                        arr.push(e.url);
                    });
                    e = arr.join(",");
                }
                this.$set(this.formData, key, e);
            },
            treeChange(e, key) {
                // this.formData[key] = e; //此方法不能双向修改
                // this.$emit('getSelectTree', e, key)
                this.$set(this.formData, key, e);
            },
            selectChange(e, key) {
                this.$set(this.formData, key, e);
            },
            datepickerChange(e, key) {
                this.$set(this.formData, key.beginKey, e[0]);
                this.$set(this.formData, key.endKey, e[1]);
            },
            cascaderChange(e, key) {
                this.$set(this.formData, key, e.join(","));
            },
            // 树形图特殊转换, 字符串转数组
            getTreeDataFun(e, i) {
                if (typeof e == "string") {
                    return e.split(",");
                } else {
                    return e
                }
            },
            // 下拉选择转换, 字符串转数组(多选)
            selectDataFun(e, i) {
                if (typeof e == "string") {
                    return e.split(",");
                } else {
                    return e;
                }
            },
            datepickerDataFun(beginValue, endValue, beginKey, endKey) {
                return beginValue
                    ? [
                        moment(beginValue).format("YYYY-MM-DD HH:mm:ss"),
                        moment(endValue).format("YYYY-MM-DD HH:mm:ss")
                    ]
                    : [];
                // return beginValue ? [beginValue, endValue] : [];
            },
            cascaderDataFun(e, i) {
                if (typeof e == "string") {
                    return e.split(",");
                }
            },
            // // 上传文件回传
            // getUploadData(e, i) {
            //   if (typeof e == "string" && e) {
            //     const arr = e.split("*");
            //     return [{ name: arr[arr.length - 1], url: e }];
            //   }
            // },
            /**
             * 初始化表单验证
             */
            initRules() {
                let rules = {};
                this.formItems.map(item => {
                    rules[item.key] = [];
                    /**
                     * 校验规则初始化
                     */
                    if (item.rule) {
                        if (typeof item.rule == "string") {
                            rules[item.key].push(this.ruleTypes[item.rule]);
                        } else {
                            item.rule.map(ruleItem => {
                                if (ruleItem.indexOf("|") != -1) {
                                    let arr = ruleItem.split("|");
                                    let arrVal = arr[1].split("~");
                                    switch (arr[0]) {
                                        case "MIN":
                                            rules[item.key].push({
                                                min: parseInt(arr[1]),
                                                trigger: "blur",
                                                message: `长度不能小于 ${arr[1]} 位`
                                            });
                                            break;
                                        case "MAX":
                                            rules[item.key].push({
                                                max: parseInt(arr[1]),
                                                trigger: "blur",
                                                message: `长度不能大于 ${arr[1]} 位`
                                            });
                                            break;
                                        case "VAL":
                                            rules[item.key].push({
                                                validator: this.valCheck,
                                                trigger: "blur",
                                                message: `设置范围为 ${arrVal[0]} ~ ${arrVal[1]}`,
                                                valMax: `${arrVal[1]}`,
                                                valMin: `${arrVal[0]}`
                                            });
                                            break;
                                    }
                                } else {
                                    rules[item.key].push(this.ruleTypes[ruleItem]);
                                }
                            });
                        }
                    }
                    if (item.type == "phone") {
                        rules[item.key].push({
                            validator: this.checkPhone,
                            trigger: "blur"
                        });
                    }
                    if (item.check) {
                        rules[item.key].push({
                            validator: this.check,
                            trigger: "blur",
                            check: item.check,
                            checkMsg: item.checkMsg,
                            needCheck: !this.formData.id
                        });
                    }
                });
                this.rules = rules;
            },
            /**
             * 检查唯一
             */
            check(rule, value, callback) {
                // if (!value) {
                //   return callback(new Error("不能为空"));
                // }
                if (rule.needCheck) {
                    rule.check(this.formData[rule.field]).then(({ data }) => {
                        console.log(data.status);
                        if (data.data.num != 0) {
                            callback(new Error(rule.checkMsg || "已存在相同的值"));
                        } else {
                            callback();
                        }
                    });
                } else {
                    callback();
                }
            },
            /**
             * 检查取值范围
             */
            valCheck(rule, value, callback) {
                if (value > parseInt(rule.valMax) || value < parseInt(rule.valMin)) {
                    callback(new Error(rule.message));
                } else {
                    callback();
                }
            },
            // 手机号检测
            checkPhone(rule, value, callback) {
                if (value) {
                    if (isNaN(value) || value.length < 11) {
                        callback(new Error(rule.message || "手机号错误"));
                    } else {
                        callback();
                    }
                } else {
                    callback();
                }
            }
        }
    };
</script>
<style lang="scss" scoped>
    .formBox {
        ::v-deep .el-col {
            min-height: 60px;
        }
        .formTitle {
            font-size: 20px;
            font-weight: 600;
            // /deep/ .el-divider__text {
            //   font-size: 18px;
            // }
            .el-divider--horizontal {
                margin: 20px 0;
            }
        }
        ::v-deep .el-rate {
            height: 36px;
            line-height: 36px;
            .el-rate__item {
                vertical-align: baseline;
            }
        }
        ::v-deep .el-upload-list__item {
            margin: 0 20px 8px 0;
        }
        // /deep/ .el-tree-node {
        //   display: inline-block;
        //   white-space: normal;
        //   // .el-icon-caret-right:before {
        //   //   content: "";
        //   // }
        // }
    }
</style>
